#ifndef CPP_INPUT_METHOD_MANAGER_H
#define CPP_INPUT_METHOD_MANAGER_H

class Activity;
class View;
class ViewGroup;
class InputMethodBase;

typedef enum {
    KEY_NONE,
    KEY_CHAR, //字符按键
    KEY_FUNCTION, //功能按键
    KEY_COUNT
} KEY_TYPE;

typedef enum {
    IME_TYPE_ENGLISH = 0x01,
    IME_TYPE_PINYIN = 0x02,
    IME_TYPE_NUMBER = 0x04,
    IME_TYPE_COUNT,
    IME_TYPE_ALL = 0xFF
} IME_TYPE;

typedef struct {
    KEY_TYPE type; //按键类型
    char const *displayStrEn; //英文键盘状态时按键上显示的字符
    char const *displayStrEnNum; //英文数字键盘状态时按键上显示的字符
    char const *displayStrZh; //中文键盘状态时按键上显示的字符
    char const *displayStrZhNum; //中文数字键盘状态时按键上显示的字符
    int code; //键码
} KEY;

//@brief 输入法管理器
//@author cvte
//@description 提供输入法界面、切换等功能
class InputMethodManager {
   public:
    InputMethodManager();
    virtual ~InputMethodManager();
    static InputMethodManager* getInstance();

    //@method 设置输入法界面，默认会使用自带输入法，或者imeUi设置为nullptr也是设置为默认输入法界面
    void setImeUi(InputMethodBase* imeUi);
    //@method 设置显示输入法界面时是否隐藏状态栏，默认隐藏
    void setHideStatusBarWhileImeShow(bool show);
    //@method 显示输入法，targetView为接收输入的控件，imeUi为输入法界面，如果为nullptr就使用默认界面
    void show(View& targetView);
    //@method 显示输入法，targetView为接收输入的控件，imeUi为输入法界面，如果为nullptr就使用默认界面，imeType为支持的输入法状态，imeTypeDefault为输入法默认状态
    void show(View& targetView, int imeTypeSupport, IME_TYPE imeTypeDefault);
    //@method 隐藏输入法
    void hide();
    //@method 设置输入法类型（中文、英文等），imeType为支持的类型，imeTypeDefault为默认值
    void setImeType(int imeTypeSupport, IME_TYPE imeTypeDefault);
    //@method 获取当前输入法界面
    ViewGroup* getUi();
    //@method 设置接收输入的控件
    void setTargetView(View& targetView);
    //@method 获取接收输入的控件
    View* getTargetView();

   private:
    static InputMethodManager* sInstance;
    char mOutputPinYin[1024]; //拼音输出结果
    InputMethodBase* mImeCurrent = nullptr; //当前输入法
    Activity* mActivity = nullptr; //触发输入法的Activity
    View* mTargetView = nullptr; //输入的目标控件
    bool mHideStatusbar = true; //显示输入法界面时是否隐藏状态栏，默认隐藏
    bool mStatusBarShouldShow = true; //保存状态栏原来显示状态，用于恢复
    bool mSubStatusBarShouldShow = true; //保存副状态栏原来显示状态，用于恢复
};

#endif